/**
 * Bestpay.com.cn Inc.
 * Copyright (c) 2011-2016 All Rights Reserved.
 */
package com.aishua.fire.common.openid;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import lombok.extern.slf4j.Slf4j;


/**
 * 通信工具类
 * 
 * @author zihan
 * @time 2016-09-20
 */
@Slf4j
public class HttpClintUtils {
	
	private HttpClintUtils() {
		    throw new IllegalStateException("HttpClintUtils class");
	}
	
	/**
	 * 连接超时时间,单位：毫秒
	 */
	private static final int CONNECTION_TIME_OUT = 5000;
	/**
	 * 等待超时时间,单位：毫秒
	 */
	private static final int READ_TIME_OUT = 60000;

	
	private static final String CONTENT_TYPE = "Content_Type";

	private static final String application_json = "application/json;charset=UTF-8";
	
	/**
	 * post方式请求服务器(https协议)
	 * 
	 * @param url
	 *            请求地址
	 * @param content
	 *            参数
	 * @param charset
	 *            编码
	 * @param flag
	 *            参数类型
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws IOException
	 */
	public static String postHttps(String url, String content, String charset,
			String flag) throws NoSuchAlgorithmException, KeyManagementException, IOException {

		URL console = new URL(url);
		SSLContext sc = SSLContext.getInstance("SSL");
		sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },
				new java.security.SecureRandom());
		HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
		conn.setSSLSocketFactory(sc.getSocketFactory());
		conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
		// 读写属性
		conn.setDoOutput(true);
		conn.setDoInput(true);
		// 连接超时秒数
		conn.setConnectTimeout(CONNECTION_TIME_OUT);
		// 读取超时秒数
		conn.setReadTimeout(READ_TIME_OUT);
		// 请求方式
		conn.setRequestMethod("POST");
		conn.setDoInput(true);
		conn.setDoOutput(true);
		// 不使用缓存
		conn.setUseCaches(false);

		if ("json".equals(flag)) {
			conn.setRequestProperty(CONTENT_TYPE,application_json);
		} else if ("webService".equalsIgnoreCase(flag)) {
			conn.setRequestProperty("SOAPAction", "");
			conn.setRequestProperty(CONTENT_TYPE, "text/xml;charset=utf-8");
		} else if ("form".equalsIgnoreCase(flag)) {
			conn.setRequestProperty(CONTENT_TYPE,
					"application/x-www-form-urlencoded");
		}
		conn.connect();
		DataOutputStream out = new DataOutputStream(conn.getOutputStream());
		out.write(content.getBytes(charset));
		// 刷新、关闭
		out.flush();
		out.close();
		InputStream is = conn.getInputStream();
		InputStreamReader isr = new InputStreamReader(is, charset);
		if (is != null) {
			StringBuilder temp = new StringBuilder();
			int len = 0;
			while ((len = isr.read()) != -1) {
				temp.append((char) len);
			}
			isr.close();
			is.close();
			return temp.toString();
		}
		return null;
	}

	
	public static String postHttp(String url, String content, String charset,
			String flag) throws IOException {
		URL console = new URL(url);
		HttpURLConnection conn = (HttpURLConnection) console.openConnection();
		// 读写属性
		conn.setDoOutput(true);
		conn.setDoInput(true);
		// 连接超时秒数
		conn.setConnectTimeout(CONNECTION_TIME_OUT);
		// 读取超时秒数
		conn.setReadTimeout(READ_TIME_OUT);
		// 请求方式
		conn.setRequestMethod("POST");
		// 不使用缓存
		conn.setUseCaches(false);
		// (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
		if ("json".equals(flag)) {
			conn.setRequestProperty(CONTENT_TYPE,application_json);
		} else if ("webService".equalsIgnoreCase(flag)) {
			conn.setRequestProperty("SOAPAction", "");
			conn.setRequestProperty(CONTENT_TYPE, "text/xml;charset=utf-8");
		} else if ("form".equalsIgnoreCase(flag)) {
			conn.setRequestProperty(CONTENT_TYPE,
					"application/x-www-form-urlencoded");
		}else if("xml".equalsIgnoreCase(flag)){
			conn.setRequestProperty("Content-Type",
					"application/xml");
		}
		conn.connect();
		DataOutputStream out = new DataOutputStream(conn.getOutputStream());
		int result=conn.getResponseCode();
		
		if (content != null) {
			out.write(content.getBytes(charset));
		}
		// 刷新、关闭
		out.flush();
		out.close();
		InputStream is = conn.getInputStream();
		InputStreamReader isr = new InputStreamReader(is, charset);
		if (is != null) {
			StringBuilder temp = new StringBuilder();
			int len = 0;
			while ((len = isr.read()) != -1) {
				temp.append((char) len);
			}
			isr.close();
			is.close();
			return temp.toString();
		}else if(result!=200){
			return "timeout";
		}
		return null;
	}
	
	/**
     * 向指定URL发送GET方法的请求
     * 
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url) {
        StringBuilder sb = new StringBuilder();
        BufferedReader in = null;
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            log.info("获取openid时请求url：{}",url);
            // 遍历所有的响应头字段
            for(Map.Entry<String,List<String>> entry : map.entrySet()){
            	log.info("{}--->{}",entry.getKey(),entry.getValue());
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
            in.close();
        } catch (IOException e) {
			log.error("发送GET请求出现异常！:{}",e);
		}
        return sb.toString();
    }

	private static class TrustAnyTrustManager implements X509TrustManager {
		
		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			log.debug("checkClientTrusted has run.");
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType)
				throws CertificateException {
			log.debug("checkServerTrusted has run.");
		}

		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[] {};
		}

	}

	private static class TrustAnyHostnameVerifier implements HostnameVerifier {
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}
	
	
	/**
	 * http请求
	 * 
	 * @param requrl
	 *            URL
	 * @param params
	 *            参数
	 * @return String
	 * @throws Exception
	 */
	public static String requestHTTP(String requrl, String params) {
		try {
			log.info(params);
			URL url = new URL(requrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(CONNECTION_TIME_OUT);
			conn.setReadTimeout(READ_TIME_OUT);
			conn.setUseCaches(false);
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setRequestProperty("Content-Length",
					Integer.toString(params.length()));
			conn.setRequestProperty("Content-Type",application_json);
			OutputStreamWriter outputSW = new OutputStreamWriter(
					conn.getOutputStream(), "utf-8");
			outputSW.write(params);
			outputSW.flush();
			outputSW.close();

			log.info("ResponseCode:" + conn.getResponseCode());
			InputStream in = conn.getInputStream();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					in, "UTF-8"));
			String line;
			StringBuilder buffer = new StringBuilder(1024);
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			in.close();
			reader.close();
			return buffer.toString();
		} catch (IOException e) {
			log.error("{}",e);
			return "";
		} 
	}
	
}
